﻿#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    setWindowTitle(QStringLiteral("服务器"));
    //监听套接字
    server = new QTcpServer(this);             //指定父对象，自动回收空间
    server->listen(QHostAddress::Any,8888);    //绑定当前网卡所有的ip
    //当客户端进行连接时server会发送newConnect的信号
    connect(server , &QTcpServer::newConnection , this , &Widget::connection);
}

Widget::~Widget()
{
    delete ui;
}

/*************************************************
  Function:       display
  Description:    将通信套接字socket中接收到的内容显示到tet_write中
  Calls:          无
  Called By:      connection
  Table Accessed: 无
  Table Updated:  无
  Input:          无
  Output:         无
  Return:         void
  Others:         无
*************************************************/
void Widget::display()
{
    //从通信套接字中取出内容,显示到窗口中
    QByteArray array = socket->readAll();
    ui->tet_read->append(array);
}

/*************************************************
  Function:       connection
  Description:    从监听套接字中取出通信套接字，获取ip和端口，在tet_read中显示客
                  户端的信息和“成功链接”,并随时接收客户端发送的消息
  Calls:          display
  Called By:      Widget
  Table Accessed: 无
  Table Updated:  无
  Input:          无
  Output:         无
  Return:         void
  Others:         无
*************************************************/
void Widget::connection()
{
    //取出建立好连接的通信套接字
    socket = server->nextPendingConnection();

    //获取对方的ip和端口port
    QString ip = socket->peerAddress().toString();
    quint16 port = socket->peerPort();
    //临时用字符串显示链接信息
    QString temp = QString("[ %1 : %2 ]").arg(ip).arg(port)+QStringLiteral("成功链接");
    ui->tet_read->setText(temp);
    //链接建立好之后客户端发送消息socket会发送readyRead的信号，可以从通信套接字中取出内容
    connect(socket , &QTcpSocket::readyRead ,this,&Widget::display);
}

/*************************************************
  Function:       on_btn_send_clicked
  Description:    点击发送，若socket为空则直接返回，若不为空则将tet_write中的内容
                  写入socket发送客户端
  Calls:          无
  Called By:      无
  Table Accessed: 无
  Table Updated:  无
  Input:          无
  Output:         无
  Return:         void
  Others:         无
*************************************************/
void Widget::on_btn_send_clicked()
{
    if(NULL == socket)
    {
        return;
    }
    //获取textedit中的内容
    QString str = ui->tet_write->toPlainText();
    //将内容写入通信套接字中进行发送,socket只能写入char* 或者byte array
    //用toUtf8()可以将QString转换为字节数组（QByteArray），用.data()可以将字节数组QByteArray转换为 char*格式
    socket->write(str.toUtf8());
}

/*************************************************
  Function:       on_btn_close_clicked
  Description:    点击发送，若socket为空则直接返回，若不为空则向socket写入断开连接，
                  断开与服务器的链接并显示"链接已断开"
  Calls:          无
  Called By:      无
  Table Accessed: 无
  Table Updated:  无
  Input:          无
  Output:         无
  Return:         void
  Others:         无
*************************************************/
void Widget::on_btn_close_clicked()
{
    if(NULL == socket)
    {
        return;
    }
    socket->write(QStringLiteral("对方已断开链接").toUtf8());
    //主动断开连接
    socket->disconnectFromHost();
    socket->close();
    ui->tet_read->append(QStringLiteral("链接已断开"));
}
